package com.ssy.lingxi.contract.serviceimpl;

import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.contract.constant.Constants;
import com.ssy.lingxi.contract.entity.ApplyAmountOrderDO;
import com.ssy.lingxi.contract.entity.ContractDO;
import com.ssy.lingxi.contract.model.constant.CommonBooleanEnum;
import com.ssy.lingxi.contract.model.vo.common.response.TaskStepVO;
import com.ssy.lingxi.contract.service.IProcessFeignService;
import com.ssy.lingxi.contract.utils.FeignLogUtils;
import com.ssy.lingxi.workflow.api.feign.ProcessFeign;
import com.ssy.lingxi.workflow.api.model.contant.ProcessEnum;
import com.ssy.lingxi.workflow.api.model.vo.request.*;
import com.ssy.lingxi.workflow.api.model.vo.response.ComplexTaskCompleteVO;
import com.ssy.lingxi.workflow.api.model.vo.response.ComplexTaskDefVO;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleProcessDefVO;
import com.ssy.lingxi.workflow.api.model.vo.response.SimpleTaskCompleteVO;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 *  新工作流feign
 * @author ds
 * @date 2021/5/21
 * @version 2.0.0
 */
@Service
public class ProcessFeignServiceImpl implements IProcessFeignService {

    /**
     * 工作流接口
     */
    @Resource
    private ProcessFeign processFeign;

    @Override
    public Wrapper<ComplexTaskCompleteVO> startProcess(TaskStartVO startVO) {
        Wrapper<ComplexTaskCompleteVO> complexTaskCompleteVOWrapper = processFeign.startProcess(startVO);
        FeignLogUtils.printLog("startProcess",complexTaskCompleteVOWrapper);
        return complexTaskCompleteVOWrapper;
    }

    @Override
    public Wrapper<ComplexTaskCompleteVO> startProcessThenCompleteFirstTask(TaskStartVO startVO) {
        Wrapper<ComplexTaskCompleteVO> complexTaskCompleteVOWrapper = processFeign.startProcessThenCompleteFirstTask(startVO);
        FeignLogUtils.printLog("startProcessThenCompleteFirstTask",complexTaskCompleteVOWrapper);
        return complexTaskCompleteVOWrapper;
    }

    @Override
    public Wrapper<ComplexTaskCompleteVO> completeTask(TaskExecuteVO executeVO) {
        Wrapper<ComplexTaskCompleteVO> complexTaskCompleteVOWrapper = processFeign.completeTask(executeVO);
        FeignLogUtils.printLog("completeTask",complexTaskCompleteVOWrapper);
        return complexTaskCompleteVOWrapper;
    }

    @Override
    public Wrapper<SimpleTaskCompleteVO> startSimpleProcess(TaskStartVO startVO) {
        Wrapper<SimpleTaskCompleteVO> complexTaskCompleteVOWrapper = processFeign.startSimpleProcess(startVO);
        FeignLogUtils.printLog("startSimpleProcess",complexTaskCompleteVOWrapper);
        return complexTaskCompleteVOWrapper;
    }

    @Override
    public Wrapper<SimpleTaskCompleteVO> startSimpleProcessThenCompleteFirstTask(TaskStartVO startVO) {
        Wrapper<SimpleTaskCompleteVO> complexTaskCompleteVOWrapper = processFeign.startSimpleProcessThenCompleteFirstTask(startVO);
        FeignLogUtils.printLog("startSimpleProcessThenCompleteFirstTask",complexTaskCompleteVOWrapper);
        return complexTaskCompleteVOWrapper;
    }

    @Override
    public Wrapper<SimpleTaskCompleteVO> completeSimpleTask(TaskExecuteVO executeVO) {
        Wrapper<SimpleTaskCompleteVO> complexTaskCompleteVOWrapper = processFeign.completeSimpleTask(executeVO);
        FeignLogUtils.printLog("completeSimpleTask",complexTaskCompleteVOWrapper);
        return complexTaskCompleteVOWrapper;
    }

    @Override
    public Wrapper<List<Long>> findProcessDataIds(ProcessDataQueryVO queryVO) {
        Wrapper<List<Long>> complexTaskCompleteVOWrapper = processFeign.findProcessDataIds(queryVO);
        FeignLogUtils.printLog("findProcessDataIds",complexTaskCompleteVOWrapper);
        return complexTaskCompleteVOWrapper;
    }

    @Override
    public Wrapper<ComplexTaskDefVO> findComplexTaskDefinitions(ComplexProcessQueryVO queryVO) {
        Wrapper<ComplexTaskDefVO> complexTaskCompleteVOWrapper = processFeign.findComplexTaskDefinitions(queryVO);
        FeignLogUtils.printLog("findComplexTaskDefinitions",complexTaskCompleteVOWrapper);
        return complexTaskCompleteVOWrapper;
    }

    @Override
    public Wrapper<SimpleProcessDefVO> findSimpleExternalTaskDefinitions(ExternalProcessQueryVO queryVO) {
        Wrapper<SimpleProcessDefVO> complexTaskCompleteVOWrapper = processFeign.findSimpleExternalTaskDefinitions(queryVO);
        FeignLogUtils.printLog("findSimpleExternalTaskDefinitions",complexTaskCompleteVOWrapper);
        return complexTaskCompleteVOWrapper;
    }

    @Override
    public Wrapper<SimpleProcessDefVO> findSimpleInternalTaskDefinitions(InternalProcessQueryVO queryVO) {
        Wrapper<SimpleProcessDefVO> complexTaskCompleteVOWrapper = processFeign.findSimpleInternalTaskDefinitions(queryVO);
        FeignLogUtils.printLog("findSimpleInternalTaskDefinitions",complexTaskCompleteVOWrapper);
        return complexTaskCompleteVOWrapper;
    }

    @Override
    public List<TaskStepVO> listTaskStep(Integer processEnum, String taskId,Long memberId) {
        InternalProcessQueryVO queryVO=new InternalProcessQueryVO();
        queryVO.setProcessKey(ProcessEnum.getProcessKeyByCode(processEnum));
        queryVO.setTaskId(taskId);
        queryVO.setMemberId(memberId);
        Wrapper<SimpleProcessDefVO> listWrapper = findSimpleInternalTaskDefinitions(queryVO);
        if (listWrapper == null || listWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            throw new BusinessException(ResponseCode.CONTRACT_APPLY_AMOUNT_ORDER_WORKFLOW_ERROR);
        }
        Integer currentStep=listWrapper.getData().getCurrentStep();
        return listWrapper.getData()
                .getTasks().stream().map(r -> {
                    TaskStepVO entity = new TaskStepVO();
                    entity.setStep(r.getTaskStep());
                    entity.setRoleName(r.getRoleName());
                    entity.setTaskName(r.getTaskName());
                    // 对应工作流步骤小于等于当前执行最后一步时，则标记已执行
                    if (r.getTaskStep() <=currentStep|| Constants.COMPLETE_TASK_ID.equals(taskId)) {
                        entity.setIsExecute(CommonBooleanEnum.YES.getCode());
                    } else {
                        entity.setIsExecute(CommonBooleanEnum.NO.getCode());
                    }
                    return entity;
                }).collect(Collectors.toList());
    }
    @Override
    public List<TaskStepVO> listTaskStepOut(Integer processEnum, String taskId,Long subRoleId,Long roleId) {
        ExternalProcessQueryVO queryVO=new ExternalProcessQueryVO();
        queryVO.setProcessKey(ProcessEnum.getProcessKeyByCode(processEnum));
        queryVO.setTaskId(taskId);
        queryVO.setSubRoleId(subRoleId);
        queryVO.setRoleId(roleId);
        Wrapper<SimpleProcessDefVO> listWrapper = findSimpleExternalTaskDefinitions(queryVO);
        if (listWrapper == null || listWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            throw new BusinessException(ResponseCode.CONTRACT_APPLY_AMOUNT_ORDER_WORKFLOW_ERROR);
        }
        Integer currentStep=listWrapper.getData().getCurrentStep();
        return listWrapper.getData()
                .getTasks().stream().map(r -> {
                    TaskStepVO entity = new TaskStepVO();
                    entity.setStep(r.getTaskStep());
                    entity.setRoleName(r.getRoleName());
                    entity.setTaskName(r.getTaskName());
                    // 对应工作流步骤小于等于当前执行最后一步时，则标记已执行
                    if (r.getTaskStep() <=currentStep||Constants.COMPLETE_TASK_ID.equals(taskId)) {
                        entity.setIsExecute(CommonBooleanEnum.YES.getCode());
                    } else {
                        entity.setIsExecute(CommonBooleanEnum.NO.getCode());
                    }
                    return entity;
                }).collect(Collectors.toList());
    }

    @Override
    public ApplyAmountOrderDO completeSimpleTaskByApplyAmountOrder(ApplyAmountOrderDO entity, Integer agree) {
        TaskExecuteVO taskStartVO=new TaskExecuteVO();
        taskStartVO.setProcessKey(ProcessEnum.getProcessKeyByCode(entity.getTaskType()));
        taskStartVO.setMemberId(entity.getMemberId());
        taskStartVO.setRoleId(entity.getRoleId());
        taskStartVO.setDataId(entity.getId());
        taskStartVO.setAgree(agree);
        taskStartVO.setTaskId(entity.getTaskId());
        Wrapper<SimpleTaskCompleteVO> taskResult = completeSimpleTask(taskStartVO);
        if (taskResult == null || taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            throw new BusinessException(ResponseCode.CONTRACT_APPLY_AMOUNT_ORDER_WORKFLOW_ERROR);
        }
        String taskId=taskResult.getData().getTaskId();
        entity.setTaskId(StringUtils.hasLength(taskId)?taskId:Constants.COMPLETE_TASK_ID);
        entity.setTaskStep(taskResult.getData().getStep());
        entity.setStatus(taskResult.getData().getStatus());
        return entity;
    }

    public ContractDO completeSimpleTaskByContractOuter(ContractDO entity, Integer agree){
        TaskExecuteVO taskStartVO=new TaskExecuteVO();
        taskStartVO.setProcessKey(ProcessEnum.getProcessKeyByCode(entity.getOuterTaskType()));
        taskStartVO.setMemberId(entity.getPartyAMemberId());
        taskStartVO.setRoleId(entity.getPartyARoleId());
        taskStartVO.setDataId(entity.getId());
        taskStartVO.setAgree(agree);
        taskStartVO.setTaskId(entity.getOuterTaskId());
        Wrapper<SimpleTaskCompleteVO> taskResult = completeSimpleTask(taskStartVO);
        if (taskResult == null || taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            throw new BusinessException(ResponseCode.CONTRACT_WORKFLOW_ERROR);
        }
        String taskId=taskResult.getData().getTaskId();
        entity.setOuterTaskId(StringUtils.hasLength(taskId)?taskId:Constants.COMPLETE_TASK_ID);
        entity.setOuterTaskStep(taskResult.getData().getStep());
        entity.setOuterStatus(taskResult.getData().getStatus());
        return entity;
    }
    public ContractDO completeSimpleTaskByContractPartyAInner(ContractDO entity, Integer agree){
        TaskExecuteVO taskStartVO=new TaskExecuteVO();
        taskStartVO.setProcessKey(ProcessEnum.getProcessKeyByCode(entity.getPartyAInnerTaskType()));
        taskStartVO.setMemberId(entity.getPartyAMemberId());
        taskStartVO.setRoleId(entity.getPartyARoleId());
        taskStartVO.setDataId(entity.getId());
        taskStartVO.setAgree(agree);
        taskStartVO.setTaskId(entity.getPartyAInnerTaskId());
        Wrapper<SimpleTaskCompleteVO> taskResult = completeSimpleTask(taskStartVO);
        if (taskResult == null || taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            throw new BusinessException(ResponseCode.CONTRACT_WORKFLOW_ERROR);
        }
        String taskId=taskResult.getData().getTaskId();
        entity.setPartyAInnerTaskId(StringUtils.hasLength(taskId)?taskId:Constants.COMPLETE_TASK_ID);
        entity.setPartyAInnerTaskStep(taskResult.getData().getStep());
        entity.setPartyAInnerStatus(taskResult.getData().getStatus());
        return entity;
    }

    public ContractDO completeSimpleTaskByContractPartyBInner(ContractDO entity, Integer agree){
        TaskExecuteVO taskStartVO=new TaskExecuteVO();
        taskStartVO.setProcessKey(ProcessEnum.getProcessKeyByCode(entity.getPartyBInnerTaskType()));
        taskStartVO.setMemberId(entity.getPartyBMemberId());
        taskStartVO.setRoleId(entity.getPartyBRoleId());
        taskStartVO.setDataId(entity.getId());
        taskStartVO.setAgree(agree);
        taskStartVO.setTaskId(entity.getPartyBInnerTaskId());
        Wrapper<SimpleTaskCompleteVO> taskResult = completeSimpleTask(taskStartVO);
        if (taskResult == null || taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            throw new BusinessException(ResponseCode.CONTRACT_WORKFLOW_ERROR);
        }
        String taskId = taskResult.getData().getTaskId();
        entity.setPartyBInnerTaskId(StringUtils.hasLength(taskId)?taskId:Constants.COMPLETE_TASK_ID);
        entity.setPartyBInnerTaskStep(taskResult.getData().getStep());
        entity.setPartyBInnerStatus(taskResult.getData().getStatus());
        return entity;
    }

    /**
     * 启动简单任务
     * @author ds
     * @date 2021/5/22
     * @param memberId: 会员id
     * @param roleId: 会员角色id
     * @param processEnum: 任务枚举值
     * @param dataId: 合同id
     * @return 操作结果
     **/
    @Override
    public SimpleTaskCompleteVO startSimpleProcess(Long memberId, Long roleId, Integer processEnum, Long dataId) {
        TaskStartVO taskStartVO = new TaskStartVO();
        taskStartVO.setDataId(dataId);
        taskStartVO.setProcessKey(ProcessEnum.getProcessKeyByCode(processEnum));
        taskStartVO.setMemberId(memberId);
        taskStartVO.setRoleId(roleId);
        Wrapper<SimpleTaskCompleteVO> taskResultVOWrapper = startSimpleProcess(taskStartVO);
        if (null == taskResultVOWrapper || ResponseCode.SUCCESS.getCode() != taskResultVOWrapper.getCode()
                || null == taskResultVOWrapper.getData()) {
            throw new BusinessException(ResponseCode.CONTRACT_WORKFLOW_ERROR);
        }
        return taskResultVOWrapper.getData();
    }
}
